#ifndef __Core_Kernel_h__
#define __Core_Kernel_h__

#include <map>

#include "Core/Service.h"
#include "Core/BasicTypes.h"

namespace Orca {

	class Service;

	class LogService;
	class FileService;
	class GfxDriver;

	//--------------------------------------------------------------------------
	class Kernel {

	public:
		virtual ~Kernel() {}
		static Kernel* inst();

		//------------------------------
		void registerDefaultModules();

		bool startup();
		void step();
		void shutdown();
		
		virtual uint32 getCurrentTime() = 0;

		//------------------------------
		template<class service_type>
		bool registerService(service_type *moduleInst) {

			if(Service::UNREGISTERED_SERVICE != service_type::msServiceId)
				return false;

			service_type::msServiceId = (uint32)mModules.size();
			mModules[service_type::msServiceId] = moduleInst;

			return true;
		}

		//------------------------------
		template<class service_type>
		service_type* getService() {

			if(Service::UNREGISTERED_SERVICE == service_type::msServiceId)
				return NULL;

			return static_cast<service_type*>(mModules[service_type::msServiceId]);
		}

	protected:
		static Kernel* msInst;

		virtual LogService*		_createLogService() = 0;
		virtual FileService*	_createFileService() = 0;
		virtual GfxDriver*		_createGfxDriver() = 0;

	private:
		typedef std::map<uint32, Service*> ModuleList;
		typedef ModuleList::iterator ModuleIter;

		ModuleList mModules;

	};

	template<class service_type>
	inline service_type* INST()
	{
		return Kernel::inst()->getService<service_type>();
	}

}

#endif	// __Core_Kernel_h__